package math;

public class Matrix 
{
    public double[][] data;
    public int height;
    public int width;
	
    public Matrix(int r, int c)
    {
	data = new double[r][c];
	height = r;
	width = c;
    }
    public Matrix(double[][] d)
    {
	height = d.length;
	width = d[0].length;
	data = new double[height][width];
	for (int r = 0; r < height; r++)
            for (int c = 0; c < width; c++)
        	this.data[r][c] = d[r][c];
    }
    public Matrix(Matrix arg)
    {
	this(arg.data);
    }
    public void swapRows(int a, int b)
    {
	double[] temp = data[a];
	data[a] = data[b];
	data[b] = temp;
    }
    public void transpose()
    {
	Matrix temp = new Matrix(this.width, this.height);
	for(int r = 0; r<height; r++)
	    for(int c = 0; c<width; c++)
		this.data[c][r] = temp.data[r][c];
    }
    public Matrix getTranspose()
    {
	Matrix temp = new Matrix(this.width, this.height);
	for(int r = 0; r<height; r++)
	    for(int c = 0; c<width; c++)
		temp.data[c][r] = this.data[r][c];
	return temp;
    }
    public boolean dimMatch(Matrix arg)
    {
	return (this.height == arg.height && this.width == arg.width);
    }
    public boolean equals(Matrix arg)
    {
	if(!dimMatch(arg))
	    return false;
	else
	{
	    for(int r = 0; r<height; r++)
		for(int c = 0; c<width; c++)
		    if(this.data[r][c] != arg.data[r][c])
			return false;
	}
	return true;
    }
    public Matrix plus(Matrix arg)
    {
	if(!this.dimMatch(arg))
	{
	    System.err.println("Illegal Matrix Dimensions\n");
	    return this;
	}
	Matrix res = new Matrix(height, width);
	for(int r = 0; r<height; r++)
	    for(int c = 0; c<width; c++)
		res.data[r][c] = this.data[r][c]+arg.data[r][c];
	return res;
    }
    public Matrix minus(Matrix arg)
    {
	if(!this.dimMatch(arg))
	{
	    System.err.println("Illegal Matrix Dimensions\n");
	    return this;
	}
	Matrix res = new Matrix(height, width);
	for(int r = 0; r<height; r++)
	    for(int c = 0; c<width; c++)
		res.data[r][c] = this.data[r][c]-arg.data[r][c];
	return res;
    }
    public Matrix times(Matrix arg)
    {
	if(this.width != arg.height)
	{
	    System.err.println("Illegal Matrix Dimensions\n");
	    return this;
	}
	Matrix res = new Matrix(this.height, arg.width);
	for(int r = 0; r<res.height; r++)
	    for(int c = 0; c<res.width; c++)
		for(int k = 0; k<this.width; k++)
		    res.data[r][c] += (this.data[r][k] * arg.data[k][c]);
	return res;
    }
    @Override
    public String toString()
    {
	String res = "";
	for(int r = 0; r<height; r++)
	{
	    res+="[";
	    for(int c = 0; c<width; c++)
	    {
		res+=(c == width-1)? (data[r][c])+"":(data[r][c])+", ";
	    }
	    res+="]\n";
	}
	return res;
    }
}
